package com.fast.util;

import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWTHeader;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author hjw
 * @since 2022年03月24日 16:37:00
 */
public class JwtUtil {
    /**
     * 密钥
     */
    public static final String key = "jwt_security";

    /**
     * 过期时间，单位毫秒
     */
    public static final long exp = 50000;

    public static String create(Map<String, Object> info) {


        /*
         * 头部
         */
        Map<String, Object> headers = new HashMap<>();
        //类型
        headers.put(JWTHeader.TYPE, "JWT");
        //内容类型
        headers.put(JWTHeader.CONTENT_TYPE, "user");
        //使用的加密算法类型
        headers.put(JWTHeader.ALGORITHM, "HS256");
        //头部唯一id
        headers.put(JWTHeader.KEY_ID, UUID.randomUUID().toString());

        /*
         * 载荷
         */
        Map<String, Object> payload = new HashMap<>();
        //唯一身份标识，可用做redis的key
        payload.put(JWTPayload.JWT_ID, UUID.randomUUID().toString());
        //jwt的签发者
//        payload.put(JWTPayload.ISSUER, SystemUtil.getHostInfo().getAddress());
        //接收jwt的一方
//        payload.put(JWTPayload.AUDIENCE, "web");
        //jwt所面向的用户
//        payload.put(JWTPayload.SUBJECT, "validator");
        //签发时间
//        payload.put(JWTPayload.ISSUED_AT, new Date());
        //生效时间
//        payload.put(JWTPayload.NOT_BEFORE, new Date());
        //过期时间
        payload.put(JWTPayload.EXPIRES_AT, new Date(System.currentTimeMillis() + exp));
        //自定义内容
        if (MapUtil.isEmpty(info)) {
            throw new IllegalArgumentException("jwt的载荷自定义内容不能为空!");
        }
        payload.putAll(info);

        /*
         *  签名
         */
        JWTSigner jwtSigner = JWTSignerUtil.hs256(key.getBytes());
        String token = JWTUtil.createToken(headers, payload, jwtSigner);
        System.out.println("token = " + token);
        return token;
    }

    public static JSONObject parse(String token) {
        verify(token);
        return JWTUtil.parseToken(token).getPayload().getClaimsJson();
    }

    public static String refresh(String token) {

        return JWTUtil.parseToken(token).getPayload().toString();
    }

    public static boolean verify(String token) {
        try {
            JWTUtil.parseToken(token);
        } catch (Exception e) {
            throw new RuntimeException("token被篡改,无法解析!");
        }

        try {
            JWTValidator.of(token).validateDate().validateAlgorithm(JWTSignerUtil.hs256(key.getBytes()));
        } catch (Exception e) {
            throw new RuntimeException("token已过期");
        }
        return true;
    }

    public static void main(String[] args) throws InterruptedException {
        Map<String, Object> info = new HashMap<>();
        info.put("userId","23234234");
        info.put("username","张三");
        String token = JwtUtil.create(info);
        JSONObject jsonObject = JwtUtil.parse("eJ0eXAiOiJKV1QiLCJraWQiOiJlNGJjZTc0ZC1lOTIwLTQ5OTgtYWRmMy02YmI2ZGRlMzIyZTUiLCJjdHkiOiJ1c2VyIiwiYWxnIjoiSFMyNTYifQ.eyJleHAiOjE2NDgxMTY2MjgsInVzZXJJZCI6IjIzMjM0MjM0IiwianRpIjoiNjlhNmU2NGItYjdkMS00NzQxLTlhZWYtMmRhZTA2ZjdhZDkzIiwidXNlcm5hbWUiOiLlvKDkuIkifQ.1aMkCO1FPi-sjddMXTeCwf5v7AvV3Ey_QtZMgOiWZFM");
        System.out.println("jsonObject = " + jsonObject);
    }
}
